﻿local L = cBnivL
cB_Filters = {}

--------------------
--General filters
--------------------

-- Bag filter
cB_Filters.fBags = function(item) return item.bagID >= 0 and item.bagID <= 4 end
--Keyring filter
cB_Filters.fKeyring = function(item) return item.bagID == -2 end
-- Bank filter
cB_Filters.fBank = function(item) return item.bagID == -1 or item.bagID >= 5 and item.bagID <= 11 end
cB_Filters.fBankFilter = function() return cBnivCfg.FilterBank end

----------------
-- Bag filters
----------------

-- Stuff filter
cB_Filters.fArmorWep = function(item)
    if not cBnivCfg.Armor then return false end
    local tC = cBniv_CatInfo[item.name]
    if tC then return (tC == "cBniv_Armor") and true or false end
    return item.type and ((item.type == L.Armor) or (item.type == L.Weapon)) 
end

-- Hide unused slots
cB_Filters.fHideEmpty = function(item) return item.link ~= nil end

-- Junk filter
cB_Filters.fJunk = function(item)
    if not cBnivCfg.Junk then return false end
    if not item.link then return false end
    local tC = cBniv_CatInfo[item.name]
    if tC then return (tC == "cBniv_Junk") and true or false end
    local _,_,tQ = GetItemInfo(item.link)
    return (tQ == 0) and true or false
end

-- Quest items filter
cB_Filters.fQuest = function(item) 
    local tC = cBniv_CatInfo[item.name]
    if tC then return (tC == "cBniv_Quest") and true or false end
    return item.type and item.type == L.Quest
end

-- Trade goods filter
cB_Filters.fTrade = function(item)
    if not cBnivCfg.TradeGoods then return false end
    local tC = cBniv_CatInfo[item.name]
    if tC then return (tC == "cBniv_TradeGoods") and true or false end
    return item.type and item.type == L.Trades 
end

-- Consumables filter
cB_Filters.fConsumables = function(item) 
    local tC = cBniv_CatInfo[item.name]
    if tC then return (tC == "cBniv_Consumables") and true or false end
    return item.type and item.type == L.Consumables 
end 

-- Cool Stuff (tm)
cB_Filters.fStuff = function(item)
    if not cBnivCfg.CoolStuff then return false end
    local tC = cBniv_CatInfo[item.name]
    if tC then return (tC == "cBniv_Stuff") and true or false end
	if not item.link then return false end
    local _,id = strsplit(":", item.link)
    id = tonumber(id)
    
    local db =  {
                6948,  -- Hearthstone
                2901,  -- Mining Pick
                7005,  -- Skinning Knife
                5956,  -- Blacksmith Hammer
                20815, -- Jeweler's Kit
                9149,  -- Philosopher's Stone
                44050, -- Mastercraft Kalu'ak Fishing Pole
                5462,  -- Dartol's Rod of Transformation
                44430, -- Titanium Seal of Dalaran
                17712, -- Winter Veil Disguise Kit
                17202, -- Snowball
                43499, -- Iron Boot Flask
                34686, -- Brazier of Dancing Flames
                32757, -- Blessed Medallion of Karabor
                37710, -- Crashin' Thrashin' Racer Controller
                }

    for _,v in ipairs(db) do 
        if id == v then return true end
    end
    return false
end

-- Soul shard filter
cB_Filters.fSoulShards = function(item)
    local t = false
    local bagType = GetItemFamily(GetBagName(item.bagID))
    if bagType then
        if (bagType == 4) then t = true end
    end
    if item.name == L.SoulShard then t = true end
    return t
end

-- Ammo filter
cB_Filters.fAmmo = function(item) 
    local tC = cBniv_CatInfo[item.name]
    if tC then return (tC == "cBniv_Ammo") and true or false end
    local t = false
    local bagType = GetItemFamily(GetBagName(item.bagID))
    if bagType then 
        if (bagType >= 1 and bagType <= 3) then t = true end
    end
    if (item.type == L.Arrow) or (item.type == L.Bullet) then t = true end
    return t
end

------------------------------------------
-- New Items filter and related functions
------------------------------------------
local Anywhere = IsAddOnLoaded('cargBags_Anywhere')
local pName = UnitName("player")

local getItemCount = function(item)
    local tHandler = cargBags:GetHandler()
	local tItemCount = 0
	for i = 0,4 do
		local tNumSlots = tHandler.GetContainerNumSlots(i)
		if tNumSlots > 0 then
			for j = 1,tNumSlots do
				local tLink = tHandler.GetContainerItemLink(i,j)
				local tName
				if tLink then tName = GetItemInfo(tLink) end
				if tName == item.name then
					local _,tStackCount = tHandler.GetContainerItemInfo(i,j)
					tItemCount = tItemCount + tStackCount
				end
			end
		end
	end
	return tItemCount
end

cB_Filters.fNewItems = function(item)
    if Anywhere then
        local _,tName = cargBags:GetHandler():GetPlayer()
        if pName ~= tName then return false end
    end
    if not cBnivCfg.NewItems then return false end
	if not ((item.bagID >= 0) and (item.bagID <= 4)) then return false end
	if not item.link then return false end
	local t = getItemCount(item)
	if not cB_KnownItems[item.name] then return true end
	return (t > cB_KnownItems[item.name]) and true or false
end

-----------------------------------------
-- Item Set filter and related functions
-----------------------------------------
local item2setEM = {} -- Blizzard Equip Manager
local item2setIR = {} -- ItemRack
local item2setOF = {} -- Outfitter
local IR = IsAddOnLoaded('ItemRack')
local OF = IsAddOnLoaded('Outfitter')

cB_Filters.fItemSets = function(item)
	if not item.link then return false end
    local tC = cBniv_CatInfo[item.name]
    if tC then return (tC == "cBniv_ItemSets") and true or false end
    -- Check ItemRack sets:
    if item2setIR[string.match(item.link,"item:(.+):%-?%d+")] then return true end
    -- Check Outfitter sets:
    local _,_,itemStr = string.find(item.link, "^|c%x+|H(.+)|h%[.*%]")
    if item2setOF[itemStr] then return true end
    -- Check Equipment Manager sets:
    local _,itemID = strsplit(":", itemStr)
    if item2setEM[tonumber(itemID)] then return true end    
   return false
end

-- Equipment Manager related
local function cacheSetsEM()
	for k in pairs(item2setEM) do item2setEM[k] = nil end
   	for k = 1, GetNumEquipmentSets() do
		local sName = GetEquipmentSetInfo(k)
        local set = GetEquipmentSetItemIDs(sName)
		for _,item in next, set do
            if item then item2setEM[item] = true end
        end
    end
    cargBags:UpdateBags()
end

local EQ_Event = CreateFrame("Frame")
EQ_Event:RegisterEvent("PLAYER_LOGIN")
EQ_Event:RegisterEvent("EQUIPMENT_SETS_CHANGED")
EQ_Event:SetScript("OnEvent", cacheSetsEM)

-- ItemRack related
local function cacheSetsIR()
    for k in pairs(item2setIR) do item2setIR[k] = nil end
    local IRsets = ItemRackUser.Sets
    for i in next, IRsets do
		if not string.find(i, "^~") then 
            for _,item in pairs(IRsets[i].equip) do
                if item then item2setIR[item] = true end
			end
		end
	end
end

if IR then
    cacheSetsIR()
    local function ItemRackOpt_CreateHooks()
        local IRsaveSet = ItemRackOpt.SaveSet
        function ItemRackOpt.SaveSet(...) IRsaveSet(...); cacheSetsIR(); cargBags:UpdateBags() end
        local IRdeleteSet = ItemRackOpt.DeleteSet
        function ItemRackOpt.DeleteSet(...) IRdeleteSet(...); cacheSetsIR(); cargBags:UpdateBags() end
    end
    local IRtoggleOpts = ItemRack.ToggleOptions
    function ItemRack.ToggleOptions(...) IRtoggleOpts(...) ItemRackOpt_CreateHooks() end
end

-- Outfitter related
local pLevel = UnitLevel("player")
local function createItemString(i) return "item:"..i.Code..":"..i.EnchantCode..":"..i.JewelCode1..":"..i.JewelCode2..":"..i.JewelCode3..":"..i.JewelCode4..":"..i.SubCode..":"..i.UniqueID..":"..pLevel end

local function cacheSetsOF()
    for k in pairs(item2setOF) do item2setOF[k] = nil end
    for _,id in ipairs(Outfitter_GetCategoryOrder()) do
        local OFsets = Outfitter_GetOutfitsByCategoryID(id)
        for _,vSet in pairs(OFsets) do
            for _,item in pairs(vSet.Items) do
                if item then item2setOF[createItemString(item)] = true end
            end
        end
    end
    cargBags:UpdateBags()
end

if OF then
	Outfitter_RegisterOutfitEvent("ADD_OUTFIT", cacheSetsOF)
	Outfitter_RegisterOutfitEvent("DELETE_OUTFIT", cacheSetsOF)
	Outfitter_RegisterOutfitEvent("EDIT_OUTFIT", cacheSetsOF)
    if Outfitter:IsInitialized() then
        cacheSetsOF()
    else
        Outfitter_RegisterOutfitEvent('OUTFITTER_INIT', cacheSetsOF)
    end
end